package org.hs.phd.common.simpleplayer.framesource;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.hs.phd.common.simpleplayer.ImageSequenceFrame;
import org.hs.phd.common.simpleplayer.Overlay;

import com.googlecode.javacv.cpp.opencv_core;
import com.googlecode.javacv.cpp.opencv_core.IplImage;

public class DefaultImageSequenceFrameImpl implements ImageSequenceFrame {

	private static class OverlayKey{
		public final Object owner;
		public final int id;
		
		public OverlayKey(Object owner, int id) {
			this.owner = owner;
			this.id = id;
		}
		

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + id;
			result = prime * result + ((owner == null) ? 0 : owner.hashCode());
			return result;
		}


		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			
			OverlayKey other = (OverlayKey) obj;
			if (id != other.id || owner != other.owner)
				return false;
			return true;
		}
		
	}
	
	private final long frameNo;
	private IplImage frameImage;
	private Map<OverlayKey,Overlay> overlays;

	public DefaultImageSequenceFrameImpl(long frameNo, IplImage frameImage) {
		this.frameNo = frameNo;
		this.frameImage = frameImage;
		overlays = new HashMap<DefaultImageSequenceFrameImpl.OverlayKey, Overlay>();
	}

	@Override
	public IplImage getFrameImage() {
		return frameImage;
	}

	@Override
	public long getFrameNo() {
		return frameNo;
	}

	@Override
	public void setFrameImage(IplImage frameImage) {
		if(this.frameImage != frameImage){
			opencv_core.cvReleaseImage(this.frameImage);
			this.frameImage = frameImage;
		}
	}

	@Override
	public void dispose() {
		opencv_core.cvReleaseImage(this.frameImage);
	}

	@Override
	public Collection<Overlay> getOverlays() {
		return overlays.values();
	}

	@Override
	public void addOverlay(Object owner, int id, Overlay overlay) {
		overlays.put( new OverlayKey(owner, id), overlay);
	}

}
